//
//  DBDatabaseConn+Initial.m
//  Pods
//
//  Created by arons on 2016/12/22.
//
//

#import "DBDatabaseConn+Initial.h"

#import "DBHead.h"

#import "GVUserDefaults+YTTProperties.h"
#import <pthread.h>


/**
 定义的当前使用的数据库版本，程序会根据版本号的改变升级数据库以及迁移旧的数据
 */
static NSString* DB_Version = @"1.1.9";
/**
 定义的数据库名称
 */
static NSString* EMOJI_DB_NAME = @"DBEmoji.sqlite";

@implementation DBDatabaseConn (Initial)

#pragma mark - ......::::::: public :::::::......

/**
 *  初始化数据库
 */
-(void)initDBWithAppGroupURL:(NSURL *)appGroupURL {
    NSURL* emojiDBURL = nil;
    if (appGroupURL) {
        emojiDBURL = [appGroupURL URLByAppendingPathComponent:EMOJI_DB_NAME];
    } else {
        emojiDBURL = [NSURL fileURLWithPath:[DOCUMENTS_DIRECTORY stringByAppendingPathComponent:EMOJI_DB_NAME]];
    }
    self.emojiDBFilePath = [emojiDBURL path];
    BOOL setAttrResult = [[NSFileManager defaultManager] setAttributes:[NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey] ofItemAtPath:self.emojiDBFilePath error:NULL];
    NSLog(@"====emojiDBFilePath:%@ setAttrResult:%d", self.emojiDBFilePath, setAttrResult);
    
    // 数据库版本控制
    [self dbVersionControl];
    
    // 拷贝数据库文件
    [self copyDefaultDBFile];
    
    // 在子线程中初始化数据表
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 数据库表初始化
        [self initTables];
    });
}

/**
 初始化默认数据
 */
- (void)initDefaultDatas {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 头像信息初始化
        // [DBHeadManager sharedDBHeadManager];
    });
}

//程序主Bundle目录
#define MAIN_BUNDLEPATH			[[NSBundle mainBundle] resourcePath]
#define RESOURCE_PATH			[MAIN_BUNDLEPATH stringByAppendingPathComponent:@"Resource"]
#define getResourcePath(path)  [RESOURCE_PATH stringByAppendingPathComponent:(path)]

#pragma mark - ......::::::: private :::::::......


/**
 拷贝默认的数据文件
 */
- (void)copyDefaultDBFile {
    
    NSString* configFilePath = @"";
    // 拷贝词库数据库文件
    if (![[NSFileManager defaultManager] fileExistsAtPath:configFilePath]) {
        
        NSString *resourcePath = getResourcePath(@"Language/DB");
        NSString* path = [resourcePath stringByAppendingPathComponent:@"OkeyStce.plist"];
        BOOL isSourceFileExist = [[NSFileManager defaultManager] fileExistsAtPath:path];
        NSLog(@"isSourceFileExist = %d", isSourceFileExist);
        
        if (isSourceFileExist) {
            NSError* err;
            [[NSFileManager defaultManager] copyItemAtPath:path toPath:configFilePath error:&err];
        }
    }
}

/**
 *  初始化数据表
 */
-(void)initTables{
    double time = [[NSDate date] timeIntervalSince1970];
    NSLog(@"initTables begtime = %f", time);
    
    // DBHead表
    [DBHead createTableIfNotExists];
    
    time = [[NSDate date] timeIntervalSince1970];
    NSLog(@"initTables endtime = %f", time);
}

#pragma mark - ......::::::: upgrade :::::::......

/**
 *  数据库版本控制
 *  版本号保存在Globals.h的宏定义中： #define DB_Version @"1.1.1"
 */
- (void)dbVersionControl {
    // 基础数据库版本管理
    [self baseDBControl];
}


/**
 数据库版本控制
 查找并且添加表字段,!!在主键没有修改的情况下可用,
 如果主键发生了变化，那么使用另一种方案:创建新的临时表，把数据导入临时表，然后用临时表替换原表
 */
- (void)baseDBControl {
    NSString * version_old = ValueOrEmpty(YTTUserDefault.dbVersion);
    NSString * version_new = [NSString stringWithFormat:@"%@", DB_Version];
    NSLog(@"dbVersionControl before: %@ after: %@",version_old,version_new);
    
    if (version_old != nil && ![version_new isEqualToString:version_old]) {
        //        NSLog(@"del db file!!!");
        //        NSFileManager *fileManager = [NSFileManager defaultManager];
        //        NSError *error;
        //        [fileManager removeItemAtPath:self.emojiDBFilePath error:&error];
        //        if (error) {
        //            NSLog(@"Can not delete DB file with error : %@",error);
        //        }
        // FIXME: ZYT 另一种方案还没实现
        // 查找并且添加表字段,!!在主键没有修改的情况下可用,
        // 如果主键发生了变化，那么使用另一种方案:创建新的临时表，把数据导入临时表，然后用临时表替换原表
        // [FLDiyTemplateItem class]
        // 需要需要更新的表的类
        NSArray* clzs = @[[DBHead class]];
        BOOL isUpgradeSuccess = YES;
        for (Class clz in clzs) {
            BOOL result = [self handleUpgradeWithTableClass:clz];
            isUpgradeSuccess &= result;
        }
        
        if(isUpgradeSuccess){
            YTTUserDefault.dbVersion = version_new;
        }
    }
}

- (BOOL)handleUpgradeWithTableClass:(Class <DBNode>)clz {
    
    NSString* sqlSnipet = [clz sqlSnipet];
    NSString* tableName = [clz tableName];
    
    __block NSMutableArray<DBColumn*>* oldColumnArr = [NSMutableArray array];
    
    [self.databaseQueue inDatabase:^(FMDatabase *db) {
        [db setKey:[DBDatabaseConn dbSecret]];
        NSString* querySql = [NSString stringWithFormat: @"pragma table_info('%@')", tableName];
        FMResultSet *rs = [db executeQuery:querySql];
        
        while ([rs next]) {
            NSString* colName = [[rs stringForColumn:@"name"] lowercaseString];
            NSString* colType = [[rs stringForColumn:@"type"] lowercaseString];
            
            DBColumn* col = [DBColumn new];
            col.columnName = colName;
            col.columnType = colType;
            [oldColumnArr addObject:col];
        }
    }];
    
    // 旧的表的字段为空，跳过
    if (oldColumnArr.count == 0) {
        return YES;
    }
    
    sqlSnipet = [sqlSnipet stringByReplacingOccurrencesOfString:@" +" withString:@" " options:NSRegularExpressionSearch range:NSMakeRange(0, sqlSnipet.length)];
    sqlSnipet = [sqlSnipet stringByReplacingOccurrencesOfString:@", " withString:@","];
    
    NSMutableArray<DBColumn*>* lastColumnArr = [NSMutableArray array];
    NSArray* sqlArr = [sqlSnipet componentsSeparatedByString:@","];
    for (NSString* sqlOneItem in sqlArr) {
        NSArray* sqlOneItemArr = [sqlOneItem componentsSeparatedByString:@" "];
        DBColumn* column = [DBColumn new];
        for (NSString* value in sqlOneItemArr) {
            if (value != nil && value.length > 0) {
                if (!column.columnName) {
                    column.columnName = value;
                }else if (!column.columnType) {
                    column.columnType = value;
                }else {
                    continue;
                }
            }
        }
        [lastColumnArr addObject:column];
    }
    
    // 得到新的需要添加的Column
    NSMutableArray<DBColumn*>* toAddColumnArr = [NSMutableArray array];
    for (DBColumn* lastCol in lastColumnArr) {
        BOOL isExist = NO;
        for (DBColumn* oldCol in oldColumnArr) {
            if ([[oldCol.columnName lowercaseString] isEqualToString:[lastCol.columnName lowercaseString]]) {
                isExist = YES;
                break;
            }
        }
        if (!isExist) {
            [toAddColumnArr addObject:lastCol];
        }
    }
    
    if (toAddColumnArr.count == 0) {
        return YES;
    }
    
    __block BOOL isUpgradeSuccess = YES;
    // 批量添加新的Colunm
    [self.databaseQueue inDatabase:^(FMDatabase *db) {
        [db setKey:[DBDatabaseConn dbSecret]];
        [db beginTransaction];
        for (DBColumn* toAddCol in toAddColumnArr) {
            NSString* sql = [NSString stringWithFormat:@"ALTER TABLE %@ ADD '%@' %@", tableName, ValueOrEmpty(toAddCol.columnName), ValueOrEmpty(toAddCol.columnType)];
            BOOL result = [db executeUpdate:sql];
            isUpgradeSuccess &= result;
            NSLog(@"result = %d  sql=%@", result, sql);
        }
        [db commit];
    }];
    return isUpgradeSuccess;
}

@end
